package com.zmc.admin.infrastructure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zmc.admin.infrastructure.constant.UserConstants;
import com.zmc.admin.infrastructure.entity.SysRoleEntity;
import com.zmc.admin.infrastructure.entity.SysUserEntity;
import com.zmc.admin.infrastructure.bean.query.SysMenuQuery;
import com.zmc.admin.infrastructure.service.SysRoleMenuService;
import com.zmc.admin.infrastructure.service.SysRoleService;
import com.zmc.admin.infrastructure.service.SysUserService;
import com.zmc.admin.infrastructure.bean.vo.menu.TreeSelect;
import com.zmc.common.utils.PageUtils;
import com.zmc.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmc.common.utils.Query;

import com.zmc.admin.infrastructure.dao.SysMenuDao;
import com.zmc.admin.infrastructure.entity.SysMenuEntity;
import com.zmc.admin.infrastructure.service.SysMenuService;
import org.springframework.util.CollectionUtils;


/**
 * @author zmc
 */
@Service("sysMenuService")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuDao, SysMenuEntity> implements SysMenuService {

    @Autowired
    private SysRoleMenuService roleMenuService;

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysUserService userService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SysMenuEntity> page = this.page(
                new Query<SysMenuEntity>().getPage(params),
                new QueryWrapper<SysMenuEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public Set<String> selectMenuPermsByUserId(Long userId) {
        return baseMapper.selectMenuPermsByUserId(userId);
    }

    @Override
    public List<SysMenuEntity> selectMenuTreeByUserId(Long userId) {
        List<SysMenuEntity> menus = null;
        SysUserEntity user = userService.getById(userId);
        if (user.isAdmin(user.getUserId())) {
            LambdaQueryWrapper<SysMenuEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByAsc(SysMenuEntity::getParentId).orderByAsc(SysMenuEntity::getOrderNum);
            menus = list(wrapper);
        } else {
            menus = baseMapper.selectMenuTreeByUserId(user.getUserId());
        }
        return getChildPerms(menus, 0);
    }

    @Override
    public List<SysMenuEntity> selectMenuList(SysMenuQuery query, SysUserEntity user) {

        List<SysMenuEntity> menuList = null;
        // 管理员显示所有菜单信息
        if (user.isAdmin(user.getUserId())) {
            menuList = baseMapper.selectMenuList(query);
        } else {
            query.setUserId(user.getUserId());
            menuList = baseMapper.selectMenuListByUserId(query);
        }
        return menuList;
    }

    @Override
    public List<TreeSelect> buildMenuTreeSelect(List<SysMenuEntity> menus) {
        List<SysMenuEntity> menuTrees = getChildPerms(menus, 0);
        List<TreeSelect> collect = menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public boolean checkMenuNameUnique(SysMenuEntity menu) {
        Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
        SysMenuEntity info = baseMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId());
        if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean hasChildByMenuId(Long menuId) {
        int result = baseMapper.hasChildByMenuId(menuId);
        return result > 0;
    }

    /**
     * 查询菜单使用数量
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean checkMenuExistRole(Long menuId) {
        int result = roleMenuService.checkMenuExistRole(menuId);
        return result > 0;
    }

    @Override
    public List<Long> selectMenuListByRoleId(Long roleId) {
        SysRoleEntity role = roleService.getById(roleId);
        return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
    }

    @Override
    public Set<String> getMenuPermission(SysUserEntity user) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin(user.getUserId())) {
            perms.add("*:*:*");
        } else {
            perms.addAll(baseMapper.selectMenuPermsByUserId(user.getUserId()));
        }
        return perms;
    }


    /**
     * 递归获取树结构
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public static List<SysMenuEntity> getChildPerms(List<SysMenuEntity> list, long parentId) {
        List<SysMenuEntity> returnList = new ArrayList<SysMenuEntity>();
        for (SysMenuEntity sysMenu : list) {
            if (sysMenu.getParentId() == parentId) {
                List<SysMenuEntity> children = getChildPerms(list, sysMenu.getMenuId());
                if (!CollectionUtils.isEmpty(children)) {
                    sysMenu.setChildren(children);
                }
                returnList.add(sysMenu);
            }
        }
        return returnList;
    }

}